﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;

namespace TMLibrary
{
    public class NavigateToBehavior : Behavior<Control>
    {
        PageTransitionBehavior pageTransitionBehavior = new PageTransitionBehavior();
        BehaviorCollection bc;
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.MouseLeftButtonUp += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
            AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
			AssociatedObject.MouseEnter +=new System.Windows.Input.MouseEventHandler(AssociatedObject_MouseEnter);
        }
        [Category("Common Properties"), Description("Gets or sets the name navigation frame"), CustomPropertyValueEditor(CustomPropertyValueEditor.Element)]
        public string FrameContainer
        {
            get;
            set;
        }
        [Category("Common Properties"), Description("Gets or sets the state to change to when opening a page")]
        public string ActiveState
        {
            get;
            set;
        }
        [Category("Common Properties"), Description("Gets or sets the inactive state ")]
        public string InactiveState
        {
            get;
            set;
        }
        void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
        {
            var mainPage = Application.Current.RootVisual as FrameworkElement;
            bc = Interaction.GetBehaviors(mainPage.FindName(FrameContainer) as UserControl);
            (mainPage.FindName(FrameContainer) as FrameworkElement).Loaded += new RoutedEventHandler(NavigateToBehavior_Loaded);
            Frame frm = FindContentFrame(mainPage.FindName(FrameContainer) as FrameworkElement);
            frm.Navigated += new System.Windows.Navigation.NavigatedEventHandler(frm_Navigated);
			
            for (int i = 0; i < bc.Count; i++)
            {
                if (bc[i] is PageTransitionBehavior)
                {
                    pageTransitionBehavior = (bc[i] as PageTransitionBehavior);
                }
            }
            pageTransitionBehavior.pNavigated += new EventHandler<PageTransitionBehavior.NavigatedEventArgs>(pageTransitionBehavior_pNavigated);
        }

        void frm_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            var mainPage = Application.Current.RootVisual as FrameworkElement;
            Frame frm = FindContentFrame(mainPage.FindName(FrameContainer) as FrameworkElement);
            if (frm != null)
            {
                if (frm.CurrentSource.ToString().Contains(Uri.ToString()))
                {
                    VisualStateManager.GoToState(AssociatedObject, ActiveState, false);
                    AssociatedObject.IsEnabled = false;
                }
                else
                {
                    VisualStateManager.GoToState(AssociatedObject, InactiveState, false);
					  AssociatedObject.IsEnabled = true;
                }
            }
        }
        Frame FindContentFrame(FrameworkElement frameContainer)
        {
            Frame frm = new Frame();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(frameContainer); i++)
            {
                if (VisualTreeHelper.GetChild(frameContainer, i) is Frame) return (VisualTreeHelper.GetChild(frameContainer, i) as Frame);
                else
                {
                    frm = FindContentFrame(VisualTreeHelper.GetChild(frameContainer, i) as FrameworkElement);
                    if (frm != null) return frm;
                }
            }
            return null;
        }

        void NavigateToBehavior_Loaded(object sender, RoutedEventArgs e)
        {
            var mainPage = Application.Current.RootVisual as FrameworkElement;
            Frame frm = FindContentFrame(mainPage.FindName(FrameContainer) as FrameworkElement);
            if (frm != null)
            {
                if (frm.CurrentSource != null)
                {
                    if (frm.CurrentSource.ToString().Contains(Uri.ToString()))
                    {
                        VisualStateManager.GoToState(AssociatedObject, ActiveState, false);
                        AssociatedObject.IsEnabled = false;
                    }
                    else
                    {
                        VisualStateManager.GoToState(AssociatedObject, InactiveState, false);
                    }
                }
            }
        }

        void pageTransitionBehavior_pNavigated(object sender, PageTransitionBehavior.NavigatedEventArgs e)
        {
            var mainPage = Application.Current.RootVisual as FrameworkElement;
            Frame frm = FindContentFrame(mainPage.FindName(FrameContainer) as FrameworkElement);
            Uri url;
            if (Uri.ToString().Contains(".xaml"))
                url = new Uri("/" + Uri.ToString(), UriKind.RelativeOrAbsolute);
            else url = Uri;
        }
        void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!pageTransitionBehavior.isAnimating)
            {
                pageTransitionBehavior.isFromControl = true;
                AssociatedObject.IsEnabled = false;
                if (Uri.ToString().IndexOf(".xaml") != -1)
                    pageTransitionBehavior.NavigateTo(new Uri("/" + Uri.ToString(), UriKind.RelativeOrAbsolute));
                else pageTransitionBehavior.NavigateTo(Uri);
            }
        }
        [Category("Common Properties"), Description("Gets or sets the page URI (.xaml file) or URI alias (must be set up in the UriMapper object")]
        public Uri Uri
        {
            get { return (Uri)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }
        public static readonly DependencyProperty UriProperty =
            DependencyProperty.Register("Uri", typeof(Uri), typeof(NavigateToBehavior), new PropertyMetadata(new Uri("", UriKind.RelativeOrAbsolute)));
        protected override void OnDetaching()
        {
            base.OnDetaching();
        }
        private void AssociatedObject_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
        	if (!pageTransitionBehavior.isAnimating) VisualStateManager.GoToState(AssociatedObject, ActiveState, true);
			else VisualStateManager.GoToState(AssociatedObject, InactiveState, true);
        }
    }
}